Java基础知识(九)

Author Avatar
子语 2017 - 10 - 15
  • 在其它设备中阅读本文章

代码块

代码块是{}定义的一段语句,根据定义的位置和关键字的不同,代码块分为四种:普通代码块,构造块,静态块和同步代码块

普通代码块

1.写在方法中的代码块,称为普通代码块

public class Demo {
    public static void main(String[] args) {
        { // 普通代码块
            int num = 10; // 局部变量
            System.out.println("num = " + num); // 10
        }
        int num = 100; // 全局变量
        System.out.println("num = " + num); // 100
    }
}

普通代码块的功能是防止方法中代码过多时出现变量重名问题,对方法的代码进行局部分割。**编写方法时,代码不应太长,**因此也没必要使用普通代码块。

构造块

1.写在类中的代码块,称为构造块

class Book {
    public Book(){ // 构造方法
        System.out.println("A. Book类的构造方法");
    }
    { // 构造块
        System.out.println("B. Book类的构造块");
    }
}

public class Demo {
    public static void main(String[] args) {
        new Book();
        // B. Book类的构造块
        // A. Book类的构造方法
    }
}

输出结果显示:构造块的调用优先于构造方法。

静态块

static定义的代码块,称为静态块。静态块的使用,分为两种情况:
1.在非主类中使用

class Book {
    public Book(){ // 构造方法
        System.out.println("A. Book类的构造方法");
    }
    { // 构造块
        System.out.println("B. Book类的构造块");
    }
    static {
        System.out.println("C. Book类的静态块");
    }
}

public class Demo {
    public static void main(String[] args) {
        new Book(); // C B A
        new Book(); // B A
    }
}

结果显示:**静态块优先于构造块。**且不论实例化多少个对象,静态块只执行一次。static主要功能是为类中的static属性初始化。

class Book {
    public static String msg;
    static {
        msg = "Hello".substring(0,2);
        System.out.println("C. Book类的静态块");
    }
}

public class Demo {
    public static void main(String[] args) {
        System.out.println(Book.msg);
    }
}

2.在主类中定义

public class Demo {
    static {
        System.out.println("**************");
    }

    public static void main(String[] args) {
        System.out.println("Hello World !");
        // **************
        // Hello World !
    }
}

结果显示:静态块优先于main()方法执行。在编写测试时,可以使用静态块。

内部类

从开发角度来说,尽量不要使用内部类

内部类基本概念

1.内部类是指在一个类的内部定义其他的类。
范例:内部类

class Outer { // 外部类
    private String msg = "Hello World";

    class Inner { // 内部类
        public void print() {
            System.out.println(msg);
        }
    }

    public void fun() {
        // 实例化内部类对象,调用print()方法
        new Inner().print();
    }
}

public class Demo {
    public static void main(String[] args) {
        // 实例化外部类对象
        Outer out = new Outer();
        out.fun(); // 调用外部类方法,Hello World
    }
}

上述代码牺牲了程序的结构,实现了一个重要功能。
2.为说明内部类特点,现将内部类取出,作为一个单独的类,并要求实现与之前一样的功能。
范例:取出内部类

class Outer { 
    private String msg = "Hello World";

    public void fun() {
        new Inner().print();
    }
}

class Inner { 
    public void print() {
        System.out.println(msg);
    }
}

public class Demo {
    public static void main(String[] args) {
        Outer out = new Outer();
        out.fun(); // 报错,msg属于Outer,Inner无法调用
    }
}

(1)要想使得Inner调用msg,就需在Outer中写一个getMsg()

public String getMsg(){
    return this.msg;
}

(2)Inner要调用OutergetMsg()方法,必须实例化一个Outer对象

class Outer { 
    private String msg = "Hello World";

    public String getMsg(){
        return this.msg;
    }

    public void fun() {
        new Inner().print();
    }
}

class Inner {
    public void print() {
        System.out.println(new Outer().getMsg());
    }
}

public class Demo {
    public static void main(String[] args) {
        Outer out = new Outer();
        out.fun();
    }
}

上述的做法不合理,最好是将主方法中的Outer对象传递给Inner对象。

class Outer { 
    private String msg = "Hello World";

    public String getMsg() {
        return this.msg;
    }

    public void fun() {
        new Inner(this).print();
    }
}

class Inner {
    private Outer out;

    public Inner(Outer out) {
        this.out = out;
    }

    public void print() {
        System.out.println(this.out.getMsg());
    }
}

public class Demo {
    public static void main(String[] args) {
        Outer out = new Outer();
        out.fun();
    }
}

由此可得内部类的特点:

内部类可以直接访问外部类的私有属性和方法,外部类也可以通过内部类对象访问内部类的私有属性。

范例:访问内部类私有属性

class Outer { // 外部类
    private String msg = "Hello World";

    class Inner { // 内部类
        private  String info = "世界你好";
        public void print() {
            System.out.println(msg);
        }
    }

    public void fun() {
        // 实例化内部类对象
        Inner in = new Inner();
        // 使用内部类对象访问内部类私有属性
        System.out.println(in.info);
    }
}

public class Demo {
    public static void main(String[] args) {
        Outer out = new Outer();
        out.fun();
    }
}

3.观察代码

class Outer { // 外部类
    private String msg = "Hello World";

    class Inner { // 内部类
        private  String info = "世界你好";
        public void print() {
            System.out.println(this.msg); // 报错,找不到msg
        }
    }

    public void fun() {
        new Inner().print();
    }
}

报错原因this.msg指向的是Inner类,而Inner类中没有msg属性。因此要访问Outermsg属性,需要使用Outer.this.msg.

class Outer { // 外部类
    private String msg = "Hello World";

    class Inner { // 内部类
        public void print() {
            // 外部类.this = 外部类的当前对象
            System.out.println(Outer.this.msg); 
        }
    }

    public void fun() {
        new Inner().print();
    }
}

4.内部类的class文件名: Outer$Inner.class
直接实例化内部类对象语法:外部类.内部类 对象名 = new 外部类().new 内部类();
范例:实例化内部类对象

public class Demo {
    public static void main(String[] args) {
        Outer.Inner in = new Outer().new Inner();
        in.print();
    }
}

上述代码说明:

要想使用内部类对象,必须先实例化外部类对象。开发中一般是通过外部类访问内部类,不用创建内部类对象。

5.内部类只想被外部类使用,不能被外部调用,应使用private定义

class Outer { // 外部类
    private String msg = "Hello World";

    private class Inner { // 内部类
        public void print() {
            // 外部类.this = 外部类的当前对象
            System.out.println(Outer.this.msg);
       }
    }
}

static定义内部类

使用static定义的属性或方法不受实例化对象控制,因此使用static定义的内部类也不受外部类实例化对象控制。
1.static定义的内部类只能访问外部类中static定义的属性或方法

class Outer { // 外部类
    private String msg = "Hello World";

    static class Inner { // 内部类
        public void print() {
            System.out.println(msg); // 报错,无法引用非静态变量msg
        }
    }
}

2.static定义的内部类,相当于外部类
取得static定义的内部类对象语法:外部类.内部类 对象 = new 外部类.内部类();由该语法可知,static定义的内部类,不需要先实例化外部类对象,再实例化内部类对象,相当于内部类成了一个外部类。

class Outer { // 外部类
    private static String msg = "Hello World";

    static class Inner { // 内部类
        public void print() {
            System.out.println(msg);
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        Outer.Inner in = new Outer.Inner();
        in.print();
    }
}

方法中定义内部类

1.内部类可定义在外部类中的任意位置。在方法中定义内部类是最常见的形式。

class Outer { // 外部类
    private String msg = "Hello World";

    public void fun() {
        class Inner { // 定义在方法中的内部类
            public void print() {
                System.out.println(msg);
            }
        }
        new Inner().print();
    }
}

public class Demo {
    public static void main(String[] args) {
        new Outer().fun();
    }
}

2.方法可以接收参数,也可以定义变量
范例:访问方法中定义的参数或变量

class Outer { // 外部类
    private String msg = "Hello World";

    public void fun(int num) { // 方法参数
        double score = 99.9; // 方法变量
        class Inner { // 定义在方法中的内部类
            public void print() {
                System.out.println("属性:" + msg);
                System.out.println("方法参数:" + num);
                System.out.println("方法变量:" + score);
            }
        }
        new Inner().print();
    }
}

public class Demo {
    public static void main(String[] args) {
        new Outer().fun(100);
    }
}

方法中的内部类可以访问方法中未用关键字修饰的参数或变量,该操作仅限于JDK1.8后!在JDK1.8之前的版本严格要求:方法中的内部类只能访问final标记的参数或变量,所以上述代码在JDK1.7前应该改为如下形式:

class Outer { // 外部类
    private String msg = "Hello World";

    public void fun(final int num) { // 方法参数
       final double score = 99.9; // 方法变量
        class Inner { // 定义在方法中的内部类
            public void print() {
                System.out.println("属性:" + msg);
                System.out.println("方法参数:" + num);
                System.out.println("方法变量:" + score);
            }
        }
        new Inner().print();
    }
}

This blog is under a CC BY-NC-SA 3.0 Unported License
本文链接:http://yov.oschina.io/article/Java/Java Base/Java基础知识(九)/